using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

namespace Slaks.Graphs.Category
{
	public class CategoryReader
	{
		private const string FileNameCategoryPattern = @"\s*(?<filename>.+?)\s+(?<category>\w+)";
		private const string FileNameGroup = "filename";
		private const string CategoryGroup = "category";
		private static readonly Regex m_regex = new Regex(FileNameCategoryPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);

		private static int m_numberOfDistinctCategories = 0;
		private static ArrayList m_categoryList;
        public static void ReadCategoryFile(string filename, out Document2CategoryMap doc2catMap, out IDictionary<string,int> catFreq)
        {
            
            StreamReader reader = null;
            try
            {
                reader = new StreamReader(filename);
                CategoryFiller(reader, out doc2catMap,out catFreq);
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (reader != null) reader.Close();
            }

        }
		public static Document2CategoryMap ReadCategoryFile(string filename)
		{
			StreamReader reader = null;
			Document2CategoryMap doc2category = null;
			try
			{
				reader = new StreamReader(filename);
				doc2category = new Document2CategoryMap();
			    IDictionary<string, int> catFrequency;
			    CategoryFiller(reader, out doc2category,out catFrequency);
			}
			catch (Exception ex)
			{
				throw ex;
			}
			finally
			{
				if (reader != null) reader.Close();
			}

			return doc2category;
		}

        private static void CategoryFiller(TextReader reader,out Document2CategoryMap doc2CatMap, out IDictionary<string, int> catFreq)
		{
			catFreq = new Dictionary<string,int>();
            doc2CatMap = new Document2CategoryMap();
			string line;
            while ((line = reader.ReadLine()) != null)
			{
				if (line == String.Empty) continue;
				Match m = m_regex.Match(line);
				if (m.Groups.Count < 2) continue;
				string fileName = m.Groups[FileNameGroup].Value;
				string category = m.Groups[CategoryGroup].Value;

				if (catFreq.ContainsKey(category) == false)
				{
				    catFreq.Add(category, 1);
				}
				else
				{
				    catFreq[category]++;
				}

                doc2CatMap.Add(fileName, category);
			}

			//set the number of unique categories
			m_numberOfDistinctCategories = catFreq.Count;

			m_categoryList = new ArrayList(catFreq.Keys.Count);
            foreach (string category in catFreq.Keys)
            {
                m_categoryList.Add(category);
            }
		}

		public static int GetNumberOfDistinctCategories()
		{
			return m_numberOfDistinctCategories;
		}

		public static IList GetCategoryList()
		{
			return m_categoryList;
		}
	}


}